//
//  StructController.swift
//  HHSwift
//
//  Created by 华宏 on 2019/4/24.
//  Copyright © 2019年 huahong. All rights reserved.
//

import UIKit

//值类型，赋值即是拷贝，产生一个副本，两者不关联
struct Location {
    var latitude : Double
    var longitude : Double
    
    //构造函数1,可失败的构造函数,可为nil
    init?(coordinateStr:String) {
        
        //方法一：
//        guard let commaIndex = coordinateStr.range(of: ",")?.lowerBound else { return nil }
//        guard let latitude = Double(coordinateStr[..<commaIndex]) else { return nil }
//        guard let longitude = Double(coordinateStr[coordinateStr.index(after: commaIndex)...]) else { return nil }
       
      
        //方法二：
        guard
            let commaIndex = coordinateStr.range(of: ",")?.lowerBound,
            let latitude = Double(coordinateStr[..<commaIndex]),
            let longitude = Double(coordinateStr[coordinateStr.index(after: commaIndex)...])
        else{
            return nil
           }
        
        
        self.latitude = latitude
        self.longitude = longitude
        
    }
    
    //构造函数2
    init(latitude:Double,longitude : Double) {
        self.latitude = latitude
        self.longitude = longitude
    }
    
    //里面还可以定义方法(mutating:改变自身的值，产生的副本覆盖掉原来的自己)
    //实例方法，类方法加staic修饰
   mutating func goNorth()  {
        self.longitude += 1
    }
    
    //下标
    subscript(index:Int) ->Double?{
        get{
            switch index{
                case 0:return latitude
                case 1:return longitude
                default:return nil
            }
        }
        
        set{
            assert(index >= 0 && index < 2, "Index Out Of Range")
            guard let newValue = newValue else{ return }
            switch index{
            case 0:latitude = newValue
            case 1:longitude = newValue
            default:return
            }
        }
    }
}

//结构体嵌套使用
struct Place {
    let location : Location
    var address : String = ""//设初值,var

}

//重载运算符（“=”不能重载）
struct Vector {
    var x : Double
    var y : Double
    var z : Double
}

func + (left:Vector,right:Vector) -> Vector {
    return Vector(x: left.x + right.x, y: left.y + right.y, z: left.z + right.z)
}

func +=( left:inout Vector,right:Vector) {
    left = left + right
}

// 重载负号（-）,只有一个参数  由于不知道“-”是放在参数的左侧还是右侧，故需要添加关键字prefix，代表“-”是在参数的左侧
//postfix表示操作符应在参数的后面: -v1
//infix 中间运算符
prefix func -(vector:Vector) -> Vector {
   return  Vector(x: -1 * vector.x, y: -1 * vector.y, z: -1 * vector.z)
}

//自定义运算符
//https://www.raywenderlich.com/157556/overloading-custom-operators-swift
infix operator ** : ATPrecedence
precedencegroup ATPrecedence {
    associativity: left                // 左结合
    higherThan: AdditionPrecedence     // AdditionPrecedence表示加法，优先级高于加法
    lowerThan: MultiplicationPrecedence// MultiplicationPrecedence表示乘法，优先级低于乘法
}
func **(x:Double,p:Double) -> Double {
    return pow(x, p)
}

class StructController: BaseViewController {

    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        self.title = "结构体"
        
        let myLocation = Location(latitude: 0, longitude: 0)
       _ = myLocation.latitude
        
        
        var v1 = Vector(x: 1, y: 1, z: 1)
        let v2 = Vector(x: 2, y: 2, z: 2)
        let v3 = v1 + v2
        print(v3)
        
        v1 += v3
         print(v1)
    }
    

    

}
